package com.yu1996.linkedlist;

public class DoubleLinkedListDemo {

    public static void main(String[] args) {

        HeroNode2 heroNode1 = new HeroNode2(1, "张三", "老张");
        HeroNode2 heroNode2 = new HeroNode2(2, "李四", "老李");
        HeroNode2 heroNode3 = new HeroNode2(3, "王五", "老王");
        HeroNode2 heroNode4 = new HeroNode2(4, "王五", "老王");
        HeroNode2 heroNode5 = new HeroNode2(5, "王五", "老王");
        HeroNode2 heroNode6 = new HeroNode2(6, "王五", "老王");

        DoubleLinkedList list = new DoubleLinkedList();
//        list.add(heroNode3);
//        list.add(heroNode2);
//        list.add(heroNode1);
//        list.add(heroNode4);
//        list.add(heroNode5);
//        list.add(heroNode6);

        list.addByOrder(heroNode3);
        list.addByOrder(heroNode2);
        list.addByOrder(heroNode1);
        list.addByOrder(heroNode4);
        list.addByOrder(heroNode5);
        list.addByOrder(heroNode6);
        list.list();
        System.out.println("这是修改后的----------------");
        HeroNode2 heroNode = new HeroNode2(6, "sdads", "老王");
        list.update(heroNode);
        list.list();
        System.out.println("这是删除后的----------------");
        list.delete(5);
        list.list();
    }


}

class DoubleLinkedList {
    //定义头结点
    HeroNode2 head = new HeroNode2(0, "", "");

    //获得头结点
    public HeroNode2 getHead() {
        return head;
    }


    /**
     * @Description: 向后遍历双向链表（和单链表一样）
     * @author: xing
     * @Date: 2019/8/3 10:24
     */
    public void list() {
        //判断链表是否为空
        if (head.next == null) {
            System.out.println("当前链表为空，请先添加数据");
            return;
        }

        //添加一个新的节点用于辅助遍历
        HeroNode2 temp = head.next;
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }

    /**
     * @Description 添加新的节点（默认加到链表的最后）
     * @Author xing
     * @Date 2019/7/27 22:43
     * @Param
     * @Return
     * @Exception
     */
    public void add(HeroNode2 node) {

        //添加一个新的节点用于辅助遍历
        HeroNode2 temp = head;

        //循环遍历到最后一个节点位置
        while (true) {

            if (temp.next == null) {
                break;
            }
            temp = temp.next;
        }
        //将需要插入的节点插入
        temp.next = node;
        node.pre = temp;
    }


    /**
     * @Description 根据编号排序添加新节点
     * @Author xing
     * @Date 2019/7/27 22:44
     * @Param
     * @Return
     * @Exception
     */
    public void addByOrder(HeroNode2 node) {

        //添加一个新的节点用于辅助遍历
        HeroNode2 temp = head;
        //定义标准是否重复插入  默认为false
        boolean flage = false;
        //找打编号对应的位置
        while (true) {
            //说明插入节点的编号为当前编号的最大值
            if (temp.next == null) {
                break;
            }
            //说明temp找到当前插入的位置
            if (temp.next.no > node.no) {
                break;
            } else //说明插入编号已经存在
                if (temp.next.no == node.no) {
                    flage = true;
                    break;
                }
            temp = temp.next;
        }
        //判断是否重复插入
        if (flage) {
            System.out.printf("插入编号%d已经存在，不能重复插入\n", node.no);
            return;
        }
        node.next = temp.next;
        //判断是否为最后一个节点
        if (temp.next != null) {
            temp.next.pre = node;
        }
        temp.next = node;
        node.pre = temp;
    }

    /**
     * @Description 更新某个节点
     * @Author xing
     * @Date 2019/7/27 22:44
     * @Param
     * @Return
     * @Exception
     */
    public void update(HeroNode2 newNode) {
        //判断链表是否为空
        if (head.next == null) {
            System.out.println("当前链表为空，请先添加数据");
            return;
        }
        //添加一个新的节点用于辅助遍历
        HeroNode2 temp = head.next;
        //用于判断是否找到标号相同的节点
        boolean flag = false;
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.no == newNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.name = newNode.name;
            temp.nickName = newNode.nickName;
        } else {
            System.out.printf("没有找到编号为%d的节点,无法修改\n", newNode.no);
        }
    }

    /**
     * @Description 删除某个节点（根据no编号删除）
     * @Author xing
     * @Date 2019/7/27 22:44
     * @Param
     * @Return
     * @Exception
     */
    public void delete(int no) {
        //判断链表是否为空
        if (head.next == null) {
            System.out.println("当前链表为空，请先添加数据");
            return;
        }
        //添加一个新的节点用于辅助遍历
        HeroNode2 temp = head.next;
        //用于判断是否找到编号相同的节点
        boolean flag = false;
        while (true) {
            //temp当前为最后一个节点，跳出循环，未找到需要删除的节点
            if (temp == null) {
                break;
            }
            if (temp.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //实现自我删除
            temp.pre.next = temp.next;
            //这里可能删除的是最后一个节点，可能会出空指针异常
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
        } else {
            System.out.printf("没有找到编号为%d的节点,无法删除\n", no);
        }
    }


}

class HeroNode2 {
    public int no; //编号
    public String name; //姓名
    public String nickName; //别名
    public HeroNode2 next;  //下一个节点
    public HeroNode2 pre;  //下一个节点

    public HeroNode2(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}